#!/usr/bin/env python
# encoding: utf-8
"""
@author:zwb
@file: serializer.py
@contact: zwb15083976291@163.com
@time: 2022/02/21
"""
from django.db import transaction
from rest_framework import serializers

from common.models import BlogWebInfo, BlogUser, BlogPages, BlogArticle, BlogTagArticle, BlogCategorie, BlogTag, \
    BlogMusics, BlogLink, BlogMessage, BlogComments
from utils.random_header_image import get_head_portrait
from utils.serializers import SpecifySerializeFieldSerializer, SpecifySerializeFieldModelSerializer
from utils.serializers.serializer import PaginatorSerializer, UpdateBaseSerializeMethodMixin


class BlogWebInfoSerializer(SpecifySerializeFieldModelSerializer):
    class Meta:
        model = BlogWebInfo
        exclude = ('id',)


class UserSerializer(SpecifySerializeFieldModelSerializer):
    class Meta:
        model = BlogUser
        exclude = ('id', 'password')


class PageConfigSerializer(SpecifySerializeFieldModelSerializer):
    class Meta:
        model = BlogPages
        exclude = ('create_time', 'update_time')


# 文章
class FrontEndArticleSerializer(UpdateBaseSerializeMethodMixin, SpecifySerializeFieldModelSerializer):
    id = serializers.IntegerField()
    article_describe = serializers.CharField(write_only=True)

    class Meta:
        model = BlogArticle
        fields = '__all__'

    def validate_id(self, value):
        if not BlogArticle.objects.filter(articles_status=0).filter(id=value).exists():
            raise serializers.ValidationError("文章不存在")
        return value

    def to_representation(self, instance):
        data = super().to_representation(instance)
        tags_id = BlogTagArticle.objects.filter(article_id=data.get('id')).values_list('tag_id', flat=True).order_by(
            "id")
        tags_data = BlogTag.objects.filter(id__in=tags_id).values("id", "tag_name")
        data['tags'] = tags_data
        categorie = BlogCategorie.objects.filter(id=data['categorie']).first()
        data["categorie"] = dict(id=categorie.id, categorie_name=categorie.categorie_name)
        # data['articles_is_topping'] = bool(data['articles_is_topping'])
        return data


# 文章列表
class FrontEndArticleListSerializer(FrontEndArticleSerializer):
    articles_content = serializers.CharField(write_only=True)
    article_describe = serializers.CharField()
    id = serializers.IntegerField()


# 文章列表请求检查
class FrontEndArticlesPaginatorSerializer(PaginatorSerializer):
    categorie = serializers.IntegerField()
    tag = serializers.CharField()

    def validate_categorie(self, value):
        if not BlogCategorie.objects.filter(id=value).exists():
            raise serializers.ValidationError("分类不存在")
        return value

    def validate_tag(self, value):
        if not BlogTag.objects.filter(id=value).exists():
            raise serializers.ValidationError("分类不存在")
        return value


# 文章推荐
class ArticlerecommendSerializer(UpdateBaseSerializeMethodMixin, SpecifySerializeFieldModelSerializer):
    id = serializers.IntegerField()

    class Meta:
        model = BlogArticle
        fields = '__all__'

    def validate_id(self, value):
        if not BlogArticle.objects.filter(articles_status=0).filter(id=value).exists():
            raise serializers.ValidationError("文章不存在")
        return value


# 文章归档
class ArticleArchivesSerializer(ArticlerecommendSerializer):
    id = serializers.IntegerField()


# 文章分类
class CategoriesSerializer(UpdateBaseSerializeMethodMixin, SpecifySerializeFieldModelSerializer):
    id = serializers.IntegerField()

    class Meta:
        model = BlogCategorie
        fields = '__all__'

    def validate_id(self, value):
        if not BlogCategorie.objects.filter(id=value).exists():
            raise serializers.ValidationError('分类不存在')
        return value


# 文章标签
class TagsSerializer(UpdateBaseSerializeMethodMixin, SpecifySerializeFieldModelSerializer):
    id = serializers.IntegerField()

    class Meta:
        model = BlogTag
        fields = '__all__'

    def validate_id(self, value):
        if not BlogTag.objects.filter(id=value).exists():
            raise serializers.ValidationError('标签不存在')
        return value


class MusicsListSerializer(SpecifySerializeFieldModelSerializer):
    id = serializers.IntegerField()

    class Meta:
        model = BlogMusics
        fields = '__all__'

    def to_representation(self, instance):
        data = super().to_representation(instance)
        new_data = dict()
        # 去除 music
        for key, value in data.items():
            if 'music' in key:
                new_data[key[6:]] = value
            else:
                new_data[key] = value
        return new_data


class LinkListSerializer(UpdateBaseSerializeMethodMixin, SpecifySerializeFieldModelSerializer):
    id = serializers.IntegerField()

    class Meta:
        model = BlogLink
        fields = "__all__"


class MessageSerializer(UpdateBaseSerializeMethodMixin, SpecifySerializeFieldModelSerializer):
    id = serializers.IntegerField()
    blog_message = serializers.CharField(min_length=1)
    audit = serializers.ChoiceField(choices=[0, 1, 2])

    class Meta:
        model = BlogMessage
        fields = "__all__"

    def create(self, validated_data):
        message = BlogMessage.objects.create(blog_message=validated_data.get("blog_message"))
        return message


class SearchArticlesSerializer(SpecifySerializeFieldModelSerializer):
    id = serializers.IntegerField()
    articles_title = serializers.CharField()
    article_describe = serializers.CharField()

    class Meta:
        model = BlogArticle
        fields = "__all__"


class CommentsSerializer(UpdateBaseSerializeMethodMixin, SpecifySerializeFieldModelSerializer):
    class Meta:
        model = BlogComments
        fields = "__all__"


# 创建评论检查
class CreateCommentsSerializer(CommentsSerializer):
    id = serializers.IntegerField()
    article_id = serializers.CharField()
    email = serializers.EmailField()
    name = serializers.CharField(min_length=1)
    content = serializers.CharField(max_length=250, min_length=1)
    comments_type = serializers.ChoiceField(choices=[0, 1])

    def validate(self, attrs):
        if attrs.get("comments_type") == 0:
            article_id = attrs.get("article_id")
            article = BlogArticle.objects.filter(id=attrs.get("article_id")).first()
            if not article:
                raise serializers.ValidationError("文章不存在")
            attrs['article_name'] = article.articles_title
        else:
            attrs['article_id'] = ''

        # 父评论
        father_id = attrs.get('father_id', None)
        if father_id:
            father_comment = BlogComments.objects.filter(id=father_id).first()
            if not father_comment:
                raise serializers.ValidationError("评论不存在")
        # 回复评论
        reply_id = attrs.get('reply_id', None)
        if reply_id:
            reply_comment = BlogComments.objects.filter(id=reply_id).first()
            if not reply_comment:
                raise serializers.ValidationError("回复评论不存在")
            attrs['reply_name'] = reply_comment.name
        attrs['title_image'] = get_head_portrait()
        return attrs

    def create(self, validated_data):
        # 创建评论
        with transaction.atomic():
            data = validated_data.copy()
            if validated_data.get("comments_type") == 1:
                data['article_id'] = ''
                comments = BlogComments.objects.create(**validated_data)
            else:
                comments = BlogComments.objects.create(**validated_data)
                article = BlogArticle.objects.filter(id=validated_data.get('article_id')).first()
                article.comment_count += 1
                article.save()

        return comments


# 返回评论列表检查
class CommentsPagingSerializer(UpdateBaseSerializeMethodMixin, PaginatorSerializer):
    comments_type = serializers.ChoiceField(choices=[0, 1])
    article_id = serializers.CharField()

    def validate(self, attrs):
        if int(attrs.get('comments_type')) == 0:
            if not attrs.get('article_id', None):
                raise serializers.ValidationError("缺少关键参数")
            if not BlogArticle.objects.filter(id=attrs.get('article_id')).exists():
                raise serializers.ValidationError("参数错误")

        return attrs


# 返回评论列表检查
class CommentsChildPagingSerializer(UpdateBaseSerializeMethodMixin, PaginatorSerializer):
    comments_type = serializers.ChoiceField(choices=[0, 1])
    father_id = serializers.IntegerField()

    def validate_father_id(self, value):
        if not BlogComments.objects.filter(id=value).exists():
            raise serializers.ValidationError("数据不存在")
        return value
